package com.demo.common.util;

import java.io.*;
import java.net.URLEncoder;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.*;

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;

import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.DES;
import lombok.extern.slf4j.Slf4j;

/**
 * DemoUtil
 * 
 * @author demo
 * @data 2021-04-09 17:37:57
 */
@Slf4j
public final class DemoUtil {
    private static String desKey;

    private DemoUtil() {
        throw new IllegalStateException("Utility class");
    }

    public static void setDesKey(String key) {
        desKey = key;
    }

    public static String desEncrypt(String content) {
        DES des = SecureUtil.des(desKey.getBytes());
        return des.encryptHex(content);
    }

    public static String desDecrypt(String data) {
        DES des = SecureUtil.des(desKey.getBytes());
        return des.decryptStr(data);
    }

    public static final ResponseEntity<byte[]> buildDownloadResponse(String filename, String srcFile) {
        byte[] content = null;
        try (InputStream is = new FileInputStream(srcFile);
                ByteArrayOutputStream os = new ByteArrayOutputStream()) {
            int len = 0;
            byte[] buffer = new byte[4096];
            while ((len = is.read(buffer)) != -1) {
                os.write(buffer, 0, len);
            }
            os.flush();
            content = os.toByteArray();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return buildDownloadResponse(filename, content);
    }

    public static final ResponseEntity<byte[]> buildDownloadResponse(String filename, byte[] content) {
        return buildDownloadResponse("application/octet-stream", filename, content);
    }

    public static final ResponseEntity<byte[]> buildDownloadResponse(String contentType, String filename, byte[] content) {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", contentType);
        try {
            headers.add("Content-Disposition", "attchement;filename*=UTF-8''" + URLEncoder.encode(filename, "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            log.error(e.getMessage(), e);
            throw new RuntimeException(e);
        }
        return new ResponseEntity<>(content, headers, HttpStatus.OK);
    }

    /**
     * 生成uuid
     *
     * @return
     */
    public static String generateUuid() {
        return UUID.randomUUID().toString().replace("-", "");
    }

    @SuppressWarnings("unchecked")
    public static<T> T deepCopy(T src) throws IOException, ClassNotFoundException {
        Object obj = null;
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
        objectOutputStream.writeObject(src);
        objectOutputStream.close();
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
        ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
        obj = objectInputStream.readObject();
        objectInputStream.close();
        return (T) obj;
    }

    public static void close(InputStream is) {
        if (is != null) {
            try {
                is.close();
            } catch (Exception e) {
            }
        }
    }

    public static void close(OutputStream os) {
        if (os != null) {
            try {
                os.close();
            } catch (Exception e) {
            }
        }
    }

    public static void close(Reader reader) {
        if (reader != null) {
            try {
                reader.close();
            } catch (Exception e) {
            }
        }
    }

    public static void close(Writer writer) {
        if (writer != null) {
            try {
                writer.close();
            } catch (Exception e) {
            }
        }
    }

    public static void close(Connection connection) {
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                log.error(e.getMessage(), e);
            }
        }
    }

    public static void close(Statement statement) {
        if (statement != null) {
            try {
                statement.close();
            } catch (SQLException e) {
                log.error(e.getMessage(), e);
            }
        }
    }

    public static void block() {
        block(10000);
    }

    public static void block(long millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
        }
    }

}
